/**
 * Copyright (c) 2012-2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */
package com.nokia.example.fuelcalculator.model;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

/**
 * The model for consumption log. It holds all the individual model objects
 * (fillings).
 */
public class FuelConsumptionModel {
    Vector log;
    
    /**
     * Constructor.
     */
    public FuelConsumptionModel() {
        this.log = new Vector();
    }
    
    /**
     * Returns true if the model is empty.
     * @return boolean
     */     
    public boolean isEmpty() {
        return log.isEmpty();
    }
    
    /**
     * Returns the amount of held model objects.
     * @return int
     */
    public int getSize() {
        return log.size();
    }
    
    /**
     * Returns a ModelObject at given index.
     * @param i is for index
     * @return ModelObject
     */
    public ModelObject getObjectAt(int i) {
        return (ModelObject) log.elementAt(i);
    }
    
    /**
     * Adds a ModelObject to the consumption log.
     * @param obj 
     */
    public void addObject(ModelObject obj) {
        log.addElement(obj);        
    }
    
    /**
     * Deletes the ModelObject that was added latest to the model.
     */
    public void deleteLatest() {
        Object last = log.lastElement();
        if (last != null) {
            log.removeElement(last);
        }
    }
    
    /**
     * Populates the model from the data-array of a record.
     * @param record
     * @return true if populating was successful
     */
    public boolean populate(byte[] record) {
        if (record == null) {
            return false;
        }
        try {
            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(record));
            long timeInMillis;
            double volume;
            int distance;
            
            while (dis.available() > 0) {
                timeInMillis = dis.readLong();
                volume = dis.readDouble();
                distance = dis.readInt();
             
                ModelObject obj = ModelObject.createModelObject(timeInMillis, volume, distance);
                addObject(obj);
            }
            return true;
        } catch (IOException e) {
        }
        return false;
    }
    
    /**
     * Returns the model in a byte array form.
     * @return byte[] to be used when persisting the state of the app
     */
    public byte[] getData() {
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(baos);
            for (int i = 0; i < getSize(); i++) {
                ModelObject obj = getObjectAt(i);
                dos.writeLong(obj.getDate().getTime());
                dos.writeDouble(obj.getVolume());
                dos.writeInt(obj.getDistance());
            }
            return baos.toByteArray();
        } catch (IOException e) {
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
            }
        }
        return new byte[0];
    }
   
}
